﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using System.Linq;
using ReportWizard.Controls;
using ReportWizard.DataAccess;
using ReportWizard.Entities;
using ReportWizard.Helpers;
using ReportWizard.Interface;
using ReportWizard.Properties;

namespace ReportWizard.Forms
{
    public partial class GeneratorForm : IconForm
    {
        private enum FieldType
        {
            Text,
            Photo,
            Group
        }

        #region variables

        TableLayoutPanel _tlpTextContainer = new TableLayoutPanel();
        TableLayoutPanel _tlpPhotoContainer = new TableLayoutPanel();
        TableLayoutPanel _tlpGroupContainer = new TableLayoutPanel();

        const float ControlWidth = 550F;
        const float ControlHeight = 34F;

        #endregion

        #region properties

        private WordTemplate SelectedWordTemplate { get; set; }

        #endregion

        public GeneratorForm(Form mdiParent)
        {
            MdiParent = mdiParent;

            InitializeComponent();

            ShowCustomLeftButton = false;
        }

        private void GeneratorFormLoad(object sender, EventArgs e)
        {
            FillTemplateList();
        }

        private void GeneratorFormFormClosed(object sender, FormClosedEventArgs e)
        {
            Globals.CurrentReport = null;
        }

        private void GenerateFormClick(object sender, EventArgs e)
        {
            if (comboTemplateList.SelectedIndex >= 0 && SelectedWordTemplate != null)
            {
                lReportFileds.Text = string.Format("{0} {1}", Resources.TemplateData, comboTemplateList.Items[comboTemplateList.SelectedIndex]);

                GenerateTemplateFields(SelectedWordTemplate.Id);
                Globals.CurrentReport = new Report();
            }
        }

        private void CancelClick(object sender, EventArgs e)
        {
            Close();
        }

        private void ClearFormClick(object sender, EventArgs e)
        {
            ClearTemplateFields();
        }

        private void GenerateReportClick(object sender, EventArgs e)
        {
            CreateReport();
        }

        private void FillTemplateList()
        {
            comboTemplateList.DataSource = null;
            comboTemplateList.Items.Clear();
            List<WordTemplate> wtList = WordTemplate.Select();
            if (wtList != null)
            {
                comboTemplateList.DataSource = wtList;
            }

            comboTemplateList.SelectedValue = SelectedWordTemplate != null ? SelectedWordTemplate.Id : -1;
        }

        private void ClearTemplateFieldsLayout()
        {
            pBookmarks.Controls.Clear();
            //tlpTextBookmarksListLayout.RowCount = 0;
            //tlpTextBookmarksListLayout.ColumnCount = 0;
            //tlpTextBookmarksListLayout.Height = 0;

            //int tlpReportFieldsLayoutControlsCount = tlpTextBookmarksListLayout.Controls.Count;
            //for (int i = tlpReportFieldsLayoutControlsCount - 1; i >= 0; i--)
            //{
            //    Control fieldsLayoutControl = tlpTextBookmarksListLayout.Controls[i];
            //    if (fieldsLayoutControl != null)
            //    {
            //        tlpTextBookmarksListLayout.Controls.Remove(fieldsLayoutControl);
            //    }
            //}
        }

        private void ClearTemplateFields()
        {
            //for (int i = 0; i < tlpTextBookmarksListLayout.Controls.Count; i++)
            //{
            //    Control fieldSelectControl = tlpTextBookmarksListLayout.Controls[i];
            //    if (fieldSelectControl != null)
            //    {
            //        if (fieldSelectControl.GetType().Equals(typeof(TemplateFiledSelect)))
            //        {
            //            ((TemplateFiledSelect)fieldSelectControl).Clear();
            //        }
            //        else if (fieldSelectControl.GetType().Equals(typeof(TemplatePhotosSelect)))
            //        {
            //            ((TemplatePhotosSelect)fieldSelectControl).Clear();
            //        }
            //    }
            //}
        }

        private void CrateFields(FieldType fieldType, List<IBookmark> list, out int rowCount)
        {
            rowCount = 0;
            if (list != null && list.Count != 0)
            {
                int columnCount = Convert.ToInt32(Width / ControlWidth);
                rowCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(list.Count) / Convert.ToDouble(columnCount)));

                Label lHeader = new Label
                                    {
                                        Dock = DockStyle.Fill,
                                        TextAlign = ContentAlignment.MiddleLeft,
                                        Font = new Font("Microsoft Sans Serif", 14F, FontStyle.Regular, GraphicsUnit.Point, 204)
                                    };

                Panel pContainer = new Panel
                                       {
                                           Dock = DockStyle.Top
                                       };
                pContainer.SuspendLayout();

                pBookmarks.Controls.Add(pContainer);

                TableLayoutPanel tlpListContainer = new TableLayoutPanel
                                                        {
                                                            ColumnCount = columnCount,
                                                            RowCount = rowCount,
                                                            Dock = DockStyle.Top,
                                                            Padding = new Padding(0, 5, 0, 5),
                                                            Height = rowCount * Convert.ToInt32(ControlHeight) + 3
                                                        };

                if (fieldType == FieldType.Text)
                {
                    lHeader.Text = Resources.PartsText;
                    _tlpTextContainer = tlpListContainer;
                }
                else if (fieldType == FieldType.Photo)
                {
                    lHeader.Text = Resources.PartsPhotos;
                    _tlpPhotoContainer = tlpListContainer;
                }
                else if (fieldType == FieldType.Group)
                {
                    lHeader.Text = Resources.PartsTextGroups;
                    _tlpGroupContainer = tlpListContainer;
                }

                tlpListContainer.SuspendLayout();

                TableLayoutPanel tlpFullContainer = new TableLayoutPanel
                                                        {
                                                            ColumnCount = 1,
                                                            RowCount = 2,
                                                            Dock = DockStyle.Top,
                                                            Height = tlpListContainer.Height + 35
                                                        };
                tlpFullContainer.SuspendLayout();
                tlpFullContainer.RowStyles.Add(new RowStyle(SizeType.Absolute, 35F));
                tlpFullContainer.RowStyles.Add(new RowStyle(SizeType.Absolute, tlpListContainer.Height));

                tlpFullContainer.Controls.Add(lHeader, 0, 0);
                tlpFullContainer.Controls.Add(tlpListContainer, 0, 1);

                pContainer.Controls.Add(tlpFullContainer);
                pContainer.Height = tlpFullContainer.Height;

                int placedControls = 0;
                bool bookmarkPlaced = false;

                for (int i = 0; i < columnCount; i++)
                {
                    if (!bookmarkPlaced)
                    {
                        if (tlpListContainer.ColumnStyles.Count == i + 1)
                        {
                            tlpListContainer.ColumnStyles[i] = new ColumnStyle(SizeType.Absolute, ControlWidth);
                        }
                        else
                        {
                            tlpListContainer.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, ControlWidth));
                        }

                        for (int j = 0; j < rowCount; j++)
                        {
                            if (placedControls == list.Count)
                                bookmarkPlaced = true;

                            if (!bookmarkPlaced)
                            {
                                Control templateFiled = null;
                                if (fieldType == FieldType.Text)
                                {
                                    templateFiled = new TemplateTextSelect(list[placedControls]);
                                }
                                else if (fieldType == FieldType.Photo)
                                {
                                    templateFiled = new TemplatePhotoSelect((WordBookmark) list[placedControls]);
                                }
                                else if (fieldType == FieldType.Group)
                                {
                                    templateFiled = new TemplateTextSelect(list[placedControls]);
                                }

                                if (templateFiled != null)
                                {
                                    templateFiled.Margin = new Padding(3, 0, 3, 0);
                                    templateFiled.BackColor = (placedControls%2 == 1)
                                                                    ? SystemColors.Control
                                                                    : SystemColors.ControlLight;

                                    if (tlpListContainer.RowStyles.Count == j + 1)
                                    {
                                        tlpListContainer.RowStyles[j] = new RowStyle(SizeType.Absolute,
                                                                                        ControlHeight);
                                    }
                                    else
                                    {
                                        tlpListContainer.RowStyles.Add(new RowStyle(SizeType.Absolute, ControlHeight));
                                    }

                                    tlpListContainer.Controls.Add(templateFiled, i, j);
                                }
                                placedControls++;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    else
                    {
                        break;
                    }
                }

                tlpListContainer.ResumeLayout();
                tlpFullContainer.ResumeLayout();
                pContainer.ResumeLayout();
            }
        }

        private void GenerateTemplateFields(int templateId)
        {
            int textBookmarksRowCount = 0;
            int photoBookmarksRowCount = 0;
            int groupBookmarksRowCount = 0;

            ClearTemplateFieldsLayout();
            
            List<WordBookmark> wordBookmarks = WordBookmark.Select(templateId, false);
            List<BookmarkGroup> wordBookmarksGroups = BookmarkGroup.SelectInTemplate(templateId);

            if (wordBookmarksGroups != null)
            {
                CrateFields(FieldType.Group, new List<IBookmark>(wordBookmarksGroups), out groupBookmarksRowCount);
            }

            if (wordBookmarks != null)
            {
                List<WordBookmark> textBookmarks = wordBookmarks.Where(i => i.IsTextBookmark).ToList();
                List<WordBookmark> photoBookmarks = wordBookmarks.Where(i => !i.IsTextBookmark).ToList();

                CrateFields(FieldType.Photo, new List<IBookmark>(photoBookmarks), out photoBookmarksRowCount);
                CrateFields(FieldType.Text, new List<IBookmark>(textBookmarks), out textBookmarksRowCount);
            }

            pBookmarks.Height = (textBookmarksRowCount + photoBookmarksRowCount + groupBookmarksRowCount) * Convert.ToInt32(ControlHeight) + (3 * 50);
        }

        private void CreateReport()
        {
            if (Globals.CurrentReport != null && SelectedWordTemplate != null)
            {
                Globals.CurrentReport.ReportTemplate = SelectedWordTemplate;
                Globals.CurrentReport.Fields = new Dictionary<IBookmark, ReportBaseObject>();

                List<TableLayoutPanel> allPanels = new List<TableLayoutPanel>
                                                       {
                                                           _tlpTextContainer, 
                                                           _tlpPhotoContainer, 
                                                           _tlpGroupContainer
                                                       };

                for (int panelIndex = 0; panelIndex < allPanels.Count; panelIndex++)
                {
                    for (int i = 0; i < allPanels[panelIndex].Controls.Count; i++)
                    {
                        Control fieldSelectControl = allPanels[panelIndex].Controls[i];
                        if (fieldSelectControl != null)
                        {
                            if (fieldSelectControl.GetType().Equals(typeof (TemplateTextSelect)))
                            {
                                TemplateTextSelect tfs = (TemplateTextSelect) fieldSelectControl;
                                ReportBaseObject rbo = new ReportBaseObject(tfs.CurrentBookmark.Id, tfs.FieldValue, tfs.CurrentBookmark is BookmarkGroup);

                                Globals.CurrentReport.Fields.Add(tfs.CurrentBookmark, rbo);

                                if (!tfs.IsSelected && !string.IsNullOrEmpty(tfs.FieldValue))
                                {
                                    rbo.Insert(false, tfs.CurrentBookmark is BookmarkGroup);
                                }
                            }
                            else if (fieldSelectControl.GetType().Equals(typeof (TemplatePhotoSelect)))
                            {
                                TemplatePhotoSelect tfs = (TemplatePhotoSelect) fieldSelectControl;
                                Globals.CurrentReport.Fields.Add(tfs.CurrentBookmark, null);
                            }
                        }
                    }
                }
                
                SetFileNameForm sf = new SetFileNameForm(false)
                                         {
                                             FormCaption = Resources.InputAlternateReportFileName,
                                             Text = Resources.ReportCreating
                                         };
                if (sf.ShowDialog() != DialogResult.Cancel)
                {
                    string newName = string.Format("{0}.doc",
                                                   string.IsNullOrEmpty(sf.NewName)
                                                       ? Path.GetFileNameWithoutExtension(SelectedWordTemplate.FileName)
                                                       : sf.NewName);

                    Globals.CurrentReport.Name = newName;

                    MsWord mw = new MsWord(CheckFooterChecked);
                    new Thread(mw.CreateDocument).Start();

                    Globals.CurrentReport.SaveToArchive();
                }
            }
        }

        private void ComboTemplateListSelectedIndexChanged(object sender, EventArgs e)
        {
            SelectedWordTemplate = WordTemplate.Select(Convert.ToInt32(comboTemplateList.SelectedValue));
            //if (SelectedWordTemplate != null)
            //{
            //    lTemplateDescription.Text = SelectedWordTemplate.Description;
            //}
        }

        private void RefreshTemplateListClick(object sender, EventArgs e)
        {
            FillTemplateList();
        }
    }
}
